home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
UNIX
/
TREEPAR
/
NETWORK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-23
|
21KB
|
1,109 lines
/* network.c - read and write the network files
*
* 28.Jul.87 jimmc Initial definition
* 1.Aug.87 jimmc Add filename arg to NPlot
* 2.Aug.87 jimmc Fill in code for nets
* 12.Aug.87 jimmc Make some routines not static, add NCreate routines
* 14.Aug.87 jimmc Add Globals stuff
* 22.Sep.87 jimmc Use xalloc.h stuff
* 3.Nov.87 jimmc Add rowdir
* 6.Nov.87 jimmc xalloc, xrealloc changed: remove (char *)NULL arg
* 18.Jan.88 jimmc Use TFhandle and TkHandle instead of casts
* 26.Jan.88 jimmc Output backslash before outputting double quotes
* 27.Jan.88 jimmc Add feedthrough stuff
* 29.Feb.88 jimmc Improve robustness when doing partial place/route
*/
#include <stdio.h>
#include <ctype.h>
#include <strings.h>
#include "xalloc.h"
#include "network.h"
#include "tklex.h"
#include "tfile.h"
#include "plot.h"
extern char *index();
extern char *strsav();
Nbase *NCurBase;
static Nbase *Tbase;
static Nnet *Tnet;
static Ngroup *Tpath;
TFhandle Thandle;
char Tflag[256];
int Tflagcount = sizeof(Tflag)/sizeof(Tflag[0]);
char Tflagr[256+1];
/* VARARGS2 */
fileerror(handle,fmt,a0,a1,a2)
TkHandle handle;
char *fmt;
char *a0, *a1, *a2;
{
char buf[1200];
sprintf(buf,fmt,a0,a1,a2);
fprintf(stderr,"Line %d: %s\n",TkLineNumber(handle),buf);
}
static expand(group,size)
Ngroup *group; /* group to expand */
int size; /* size of each item in the array, in bytes */
{
if (group->count>=group->alloc) { /* need more space */
if (group->alloc==0) group->alloc = 15;
else group->alloc *= 2;
if (group->d.x) group->d.x =
(char **)xrealloc((char *)group->d.x,group->alloc*size);
else group->d.x = (char **)xalloc(group->alloc*size);
}
}
insertp(group,item)
Ngroup *group;
char *item;
{
expand(group,sizeof(char *));
group->d.x[group->count++] = item;
}
removep(group,item)
Ngroup *group;
char *item;
{
int cct,i;
cct = group->count;
for (i=cct-1; i>=0; i--) { /* find it in list */
if (group->d.x[i]==item) {
if (i<cct-1) {
group->d.x[i] = group->d.x[cct-1];
}
group->count--;
return;
}
}
}
/* Name routines */
NDumpString(f,s)
FILE *f;
char *s;
{
if (!s) {
fprintf(f,"\"\"");
return;
}
fputc('"',f);
for (;*s;s++) {
if (*s=='"') fputs("\\\"",f);
else if (isprint(*s)) fputc(*s,f);
else if (*s=='\n') fputs("\\n\\\n",f);
else fprintf(f,"\\%03o",*s);
}
fputc('"',f);
}
/* Bounding box routines */
int BBset;
static Npoint BBlow,BBhigh;
NInitBB()
{
BBset = 0;
BBlow.X = BBlow.Y = 0;
BBhigh.X = BBhigh.Y = 0;
}
NAddBB(p)
Npoint p;
{
if (!BBset) {
BBlow.X = BBhigh.X = p.X;
BBlow.Y = BBhigh.Y = p.Y;
BBset++;
}
else {
if (p.X < BBlow.X) BBlow.X = p.X;
if (p.X > BBhigh.X) BBhigh.X = p.X;
if (p.Y < BBlow.Y) BBlow.Y = p.Y;
if (p.Y > BBhigh.Y) BBhigh.Y = p.Y;
}
}
static struct _oposinfo {
char *text;
int icode;
} OposTab[] = {
"N", N,
"S", S,
"E", E,
"W", W,
"NE", NE,
"NW", NW,
"SE", SE,
"SW", SW,
"C", C,
};
static int OposTabSize = sizeof(OposTab)/sizeof(OposTab[0]);
int NGetOposInt(s)
char *s;
{
int i;
for (i=0; i<OposTabSize; i++) {
if (strcmp(s,OposTab[i].text)==0) {
return OposTab[i].icode;
}
}
return -1;
}
char *
NGetOposString(n)
int n;
{
int i;
for (i=0; i<OposTabSize; i++) {
if (n==OposTab[i].icode) return OposTab[i].text;
}
return "??";
}
/* Box routines */
Nbox *
NCreateBox(name,originx,originy,sizex,sizey,text,textx,texty,textpos,
rownum,rowpos)
char *name;
int originx,originy;
int sizex,sizey;
char *text;
int textx,texty;
char *textpos;
int rownum;
int rowpos;
{
Nbox *box;
box = XCALLOC(Nbox,1);
box->name = name;
box->origin.X = originx;
box->origin.Y = originy;
box->size.X = sizex;
box->size.Y = sizey;
box->text = text;
box->text_origin.X = textx;
box->text_origin.Y = texty;
box->text_opos = NGetOposInt(textpos);
box->rownum = rownum;
box->rowpos = rowpos;
insertp(&(Tbase->boxlist),(char *)box);
return box;
}
NSetupBox(handle)
TFhandle handle;
{
TFSetup(handle,"box",NCreateBox,
"name.s","orgx.i","orgy.i","sizex.i","sizey.i",
"text.s","textx.i","texty.i","textpos.s",
"rownum.i","rowpos.i",0);
}
NWriteBox(f,box,i)
FILE *f; /* file to write to */
Nbox *box; /* the box to write out */
int i; /* counter */
{
if (!box) return;
if (i==0) { /* write out the schema the first time */
fprintf(f,"\nbox schema (\"name.s\" \"sizex.i\" \"sizey.i\" \
\"orgx.i\" \"orgy.i\"\n\t\"text.s\" \"textx.i\" \"texty.i\" \"textpos.s\" \
\"rownum.i\" \"rowpos.i\")\n");
}
fprintf(f,"\nbox (");
NDumpString(f,box->name);
fprintf(f," %d %d %d %d ",box->size.X,box->size.Y,
box->origin.X,box->origin.Y);
NDumpString(f,box->text);
fprintf(f," %d %d \"%s\"",box->text_origin.X,box->text_origin.Y,
NGetOposString(box->text_opos));
fprintf(f," %d %d",box->rownum,box->rowpos);
fprintf(f,")\n");
}
NBoundBox(box)
Nbox *box;
{
Npoint p;
NAddBB(box->origin);
p.X = box->origin.X + box->size.X;
p.Y = box->origin.Y + box->size.Y;
NAddBB(p);
}
NPlotBox(box)
Nbox *box;
{
if (RIsFeedBox(box)) {
if (Tflag['f'])
plotx(box->origin.X,box->origin.Y);
return;
}
PBox(box->origin.X,box->origin.Y,
box->origin.X+box->size.X, box->origin.Y+box->size.Y);
if (box->text) {
if (!Tflag['T']) { /* 'T' flag turns off box text */
PText(box->origin.X+box->text_origin.X,
box->origin.Y+box->text_origin.Y,
box->text_opos,box->text);
}
if (Tflag['l']) { /* 'l' flag puts in label instead */
PText(box->origin.X+box->text_origin.X,
box->origin.Y+box->text_origin.Y,
box->text_opos,box->name);
}
}
}
Nbox *
NFindBox(base,name)
Nbase *base;
char *name; /* name of the box to find */
{
int i;
for (i=0; i<base->boxlist.count; i++) {
if (strcmp(base->boxlist.d.box[i]->name,name)==0)
return base->boxlist.d.box[i];
}
return 0;
}
NIFreeBox(box)
Nbox *box;
{
removep(&(Tbase->boxlist),(char *)box);
NFreeBox(box);
}
NFreeBox(box)
Nbox *box;
{
if (box->name) tfree(box->name);
if (box->text) tfree(box->text);
tfree(box);
}
NClearBoxConns(box)
Nbox *box;
{
box->connlist.count = 0;
}
/* Net routines */
Nnet *
NCreateNet(name,rownum)
char *name;
{
Nnet *net;
net = XCALLOC(Nnet,1);
net->name = name;
net->rownum = rownum;
Tnet = net; /* for future path input */
Tpath = 0;
insertp(&(Tbase->netlist),(char *)net);
return net;
}
NSetNet(net)
Nnet *net;
{
Tnet = net;
Tpath = 0;
}
NCreate1Path(x0,y0,x1,y1)
int x0,y0;
int x1,y1;
{
NCreatePath(x0,y0);
NCreatePath(x1,y1);
NCreateEndPath();
}
NCreatePath(x,y)
int x,y;
{
if (!Tnet) return;
if (!Tpath) {
Tpath = XCALLOC(Ngroup,1);
insertp(&(Tnet->pathlist),(char *)Tpath);
}
expand(Tpath,sizeof(Npoint));
Tpath->d.pt[Tpath->count].X = x;
Tpath->d.pt[Tpath->count++].Y = y;
}
NCreateEndPath()
{
Tpath = 0;
}
NSetupNet(handle)
TFhandle handle;
{
TFSetup(handle,"net",NCreateNet,"name.s","rownum.i",0);
TFSetup(handle,"path",NCreatePath,"x.i","y.i",0);
TFSetup(handle,"endpath",NCreateEndPath,0);
}
NWriteNet(f,net,n)
FILE *f;
Nnet *net;
int n;
{
int i,j;
Ngroup *path;
if (!net) return;
if (n==0) {
fprintf(f,"\nnet schema \
(\"name.s\" \"rownum.i\" /* angle */)\n");
fprintf(f,"path schema (\"x.i\" \"y.i\") endpath schema ()\n");
}
fprintf(f,"\nnet (");
NDumpString(f,net->name);
fprintf(f," %d",net->rownum);
fprintf(f," /* %c */",net->angle?net->angle:'0');
fprintf(f,")\n");
for (i=0; i<net->pathlist.count; i++) {
path = net->pathlist.d.path[i];
fprintf(f," path");
for (j=0; j<path->count; j++) {
fprintf(f," (%d %d)",
path->d.pt[j].X,path->d.pt[j].Y);
}
if (i<net->pathlist.count-1) fprintf(f," endpath ()");
fprintf(f,"\n");
}
}
NBoundNet(net)
Nnet *net;
{
int i,j;
Ngroup *path;
for (i=0; i<net->pathlist.count; i++) {
path = net->pathlist.d.path[i];
for (j=0; j<path->count; j++)
NAddBB(path->d.pt[j]);
}
}
NPlotNet(net)
Nnet *net;
{
int i,j;
Ngroup *path;
for (i=0; i<net->pathlist.count; i++) {
path = net->pathlist.d.path[i];
for (j=0; j<path->count-1; j++)
PLine(path->d.pt[j].X,path->d.pt[j].Y,
path->d.pt[j+1].X,path->d.pt[j+1].Y);
}
}
Nnet *
NFindNet(base,name)
Nbase *base;
char *name; /* name of the net to find */
{
int i;
for (i=0; i<base->netlist.count; i++) {
if (strcmp(base->netlist.d.net[i]->name,name)==0)
return base->netlist.d.net[i];
}
return 0;
}
NIFreeNet(net)
Nnet *net;
{
removep(&(Tbase->netlist),(char *)net);
NFreeNet(net);
}
NFreeNet(net)
Nnet *net;
{
extern int NFreeGroupOnly();
if (net->name) tfree(net->name);
NFreeGroup(&(net->pathlist),NFreeGroupOnly);
NFreeGroupOnly(&(net->connlist));
tfree(net);
}
NClearNetConns(net)
Nnet *net;
{
net->connlist.count = 0;
}
/* Conn routines */
NBoundConn(){}
static
plotx(x,y)
{
int size;
size = NCurBase->textsize.Y;
PLine(x+size,y-size,x-size,y+size);
PLine(x+size,y+size,x-size,y-size);
}
NPlotConn(conn)
Nconn *conn;
{
if (!Tflag['c']) return;
/* only plot connectors if the 'c' flag is set */
plotx(conn->apos.X,conn->apos.Y);
}
Nconn *
NCreateConn(boxname,connname,boxx,boxy,side,netname)
char *boxname; /* name of the box this conn goes to */
char *connname; /* connector name - only needs uniqeness in the box */
int boxx,boxy; /* connector coords relative to box origin */
char *side; /* which side (N,S,E,W) */
char *netname; /* name of the attached net */
{
Nconn *conn;
char *s,*dirs;
if (!connname || !*connname) {
fileerror(Thandle->tkhandle,"no name for connector");
return 0;
}
if (!boxname || !*boxname) {
fileerror(Thandle->tkhandle,"no box name for connector");
return 0;
}
if (!netname || !*netname) {
fileerror(Thandle->tkhandle,"warning: no net for connector");
}
if (!side) side="N";
conn = XCALLOC(Nconn,1);
conn->boxname = boxname;
conn->name = connname;
conn->pos.X = boxx;
conn->pos.Y = boxy;
dirs = "NSEW";
s = index(dirs,side[0]);
if (!s) conn->side = 0;
else conn->side = s-dirs;
conn->netname = netname;
insertp(&(Tbase->connlist),(char *)conn);
return conn;
}
NSetupConn(handle)
TFhandle handle;
{
TFSetup(handle,"conn",NCreateConn,"boxname.s","name.s",
"x.i","y.i","side.s","netname.s",0);
}
NWriteConn(f,conn,i)
FILE *f; /* file to write to */
Nconn *conn; /* the conn to write out */
int i; /* counter */
{
if (!conn) return;
if (i==0) { /* write out the schema the first time */
fprintf(f,"\nconn schema (\"boxname.s\" \"name.s\" \
\"x.i\" \"y.i\" ");
if (Tflag['c']) {
fprintf(f,"\"ax.i\" \"ay.i\" ");
}
fprintf(f,"\"side.s\" \"netname.s\")\n\n");
}
fprintf(f,"conn (");
NDumpString(f,conn->boxname);
fputc(' ',f);
NDumpString(f,conn->name);
fprintf(f," %d %d",conn->pos.X, conn->pos.Y);
if (Tflag['c']) {
fprintf(f," %d %d",conn->apos.X, conn->apos.Y);
}
fprintf(f," \"%c\" ","NSEW"[conn->side]);
NDumpString(f,conn->netname);
fprintf(f,")\n");
}
/* free a connector and remove it from the general conn list */
NIFreeConn(conn)
Nconn *conn;
{
removep(&(Tbase->connlist),(char *)conn);
NFreeConn(conn);
}
NFreeConn(conn)
Nconn *conn;
{
if (conn->name) tfree(conn->name);
if (conn->netname) tfree(conn->netname);
if (conn->boxname) tfree(conn->boxname);
tfree(conn);
}
NPosConn(conn) /* set the apos in a conn */
Nconn *conn;
{
if (conn->box) {
conn->apos.X = conn->box->origin.X + conn->pos.X;
conn->apos.Y = conn->box->origin.Y + conn->pos.Y;
}
}
NLinkConn(conn)
Nconn *conn;
{
NLinkConnBox(conn);
NLinkConnNet(conn);
}
NLinkConnBox(conn)
Nconn *conn;
{
Nbox *box;
box = NFindBox(Tbase,conn->boxname);
if (!box) {
printf("can't find box %s, connector %s\n",
conn->boxname, conn->name);
}
else {
conn->box = box;
insertp(&(box->connlist),(char *)conn);
NPosConn(conn);
}
}
NLinkConnNet(conn)
Nconn *conn;
{
Nnet *net;
net = NFindNet(Tbase,conn->netname);
if (!net) {
net = NCreateNet(strsav(conn->netname),0);
}
conn->net = net;
insertp(&(net->connlist),(char *)conn);
}
NUnLinkConnNet(conn)
Nconn *conn;
{
Nnet *net;
net = conn->net;
if (!net) return;
removep(&(net->connlist),(char *)conn);
conn->net = 0;
}
/* Row routines */
NBoundRow(){}
NPlotRow(){}
NCreateRow(rownum,size,pos)
int rownum;
int size;
int pos;
{
Nrow *row;
row = XCALLOC(Nrow,1);
row->rownum = rownum;
row->size = size;
row->pos = pos;
insertp(&(Tbase->rowlist),(char *)row);
}
NSetupRow(handle)
TFhandle handle;
{
TFSetup(handle,"row",NCreateRow,"rownum.i","size.i","pos.i",0);
}
NWriteRow(f,row,i)
FILE *f; /* file to write to */
Nrow *row; /* the row to write out */
int i; /* counter */
{
if (!row) return;
if (i==0) { /* write out the schema the first time */
fprintf(f,"\nrow schema (\"rownum.i\" \"size.i\" \
\"pos.i\")\n\n");
}
fprintf(f,"row (%d %d %d", row->rownum, row->size, row->pos);
fprintf(f,")\n");
}
NFreeRow(row)
Nrow *row;
{
tfree(row);
}
/* globals routines */
static
NDefaultGlobals(base)
Nbase *base;
{
base->textsize.X = 1;
base->textsize.Y = 1;
base->interrowspace = 3;
base->rowposspace = 2;
base->trackspace = 2;
base->rowdir = 'H';
base->label.s = 0;
}
static
NCreateGlobals(textsizex,textsizey,interrowspace,rowposspace,trackspace,
rowdir,label)
int textsizex, textsizey;
int interrowspace;
int rowposspace;
int trackspace;
char *rowdir;
char *label;
{
Tbase->textsize.X = textsizex;
Tbase->textsize.Y = textsizey;
Tbase->interrowspace = interrowspace;
Tbase->rowposspace = rowposspace;
Tbase->trackspace = trackspace;
if (rowdir && (rowdir[0]=='V' || rowdir[0]=='H'))
Tbase->rowdir = rowdir[0];
/*** else error */
Tbase->label.s = label;
}
static
NSetupGlobals(handle)
TFhandle handle;
{
TFSetup(handle,"globals",NCreateGlobals,"textsizex.i","textsizey.i",
"interrowspace.i","rowposspace.i","trackspace.i",
"rowdir.s","label.s",0);
}
static
NWriteGlobals(f,base)
FILE *f;
Nbase *base;
{
fprintf(f,"\nglobals schema (\"textsizex.i\" \"textsizey.i\" \
\"interrowspace.i\" \"rowposspace.i\" \"trackspace.i\" \
\"rowdir.s\" \"label.s\")\n");
fprintf(f,"(%d %d %d %d %d \"%c\" ",
base->textsize.X, base->textsize.Y,
base->interrowspace, base->rowposspace,
base->trackspace, base->rowdir);
NDumpString(f,base->label.s);
fprintf(f,")\n");
}
/* label routines */
/* ARGSUSED (so far!) */
int /* 1 if OK to go there */
NCheckLabel(base,where)
Nbase *base;
int where; /* compass code */
{
return 0; /*** not yet done! */
}
NSetLabel(base)
Nbase *base;
{
char *cp, *cp2;
int xsize, ysize;
int l;
if (!base->label.s || !base->label.s[0]) return;
cp = base->label.s;
xsize = 0;
ysize = 0;
while (cp && *cp) {
cp2 = index(cp,'\n');
if (!cp2) l=strlen(cp);
else l=(cp2++)-cp;
if (l>xsize) xsize=l;
ysize++;
cp = cp2;
}
base->label.tsize.X = xsize;
base->label.tsize.Y = ysize;
if (NCheckLabel(base,SW)) {
}
else if (NCheckLabel(base,SE)) {
}
else {
base->label.origin.X = 0; /*** not right! */
base->label.origin.Y = -(ysize+3)*base->textsize.Y;
}
}
NBoundLabel(base)
Nbase *base;
{
Npoint p;
if (!base->label.s || !base->label.s[0]) return;
NAddBB(base->label.origin);
p.X = base->label.origin.X + (base->label.tsize.X+2)*base->textsize.X;
p.Y = base->label.origin.Y + (base->label.tsize.Y+2)*base->textsize.Y;
NAddBB(p);
}
NPlotLabel(base)
Nbase *base;
{
Npoint p;
if (!base->label.s || !base->label.s[0]) return;
p.X = base->label.origin.X + (base->label.tsize.X+2)*base->textsize.X;
p.Y = base->label.origin.Y + (base->label.tsize.Y+2)*base->textsize.Y;
PBox(base->label.origin.X,base->label.origin.Y,p.X,p.Y);
if (!Tflag['T']) { /* 'T' flag turns off text */
PText(base->label.origin.X+base->textsize.X,
base->label.origin.Y+base->textsize.Y,
SW,base->label.s);
}
}
/* Group routines */
NDumpGroup(f,group,funcp)
FILE *f;
Ngroup *group;
int (*funcp)();
{
int i;
for (i=0; i<group->count ;i++)
(*funcp)(f,group->d.x[i],i);
}
NDoGroup(group,funcp)
Ngroup *group;
int (*funcp)();
{
int i;
for (i=0;i<group->count;i++)
(*funcp)(group->d.x[i]);
}
NRDoGroup(group,funcp)
Ngroup *group;
int (*funcp)();
{
int i;
for (i=group->count-1;i>=0;i--)
(*funcp)(group->d.x[i]);
}
NClearGroup(group)
Ngroup *group;
{
group->count = group->alloc = 0;
group->d.x = 0;
}
NFreeGroupOnly(group)
Ngroup *group;
{
if (group->d.x)
tfree(group->d.x);
NClearGroup(group);
}
NFreeGroup(group,funcp)
Ngroup *group;
int (*funcp)();
{
NDoGroup(group,funcp);
NFreeGroupOnly(group);
}
/* Base routines */
NSetBase(base)
Nbase *base;
{
Tbase = base;
}
NFreeNetwork(base) /* deallocates everything */
Nbase *base;
{
if (!base) return;
NFreeGroup(&(base->boxlist),NFreeBox);
NFreeGroup(&(base->netlist),NFreeNet);
NFreeGroup(&(base->connlist),NFreeConn);
NFreeGroup(&(base->rowlist),NFreeRow);
tfree(base);
}
Nbase *
NReadNetwork(filename)
char *filename;
{
TFhandle handle;
Tbase = XCALLOC(Nbase,1);
Thandle = handle = TFInit(filename);
if (!handle) {
printf("can't open file %s",filename);
return 0;
}
NDefaultGlobals(Tbase);
NSetupGlobals(handle);
NSetupBox(handle);
NSetupNet(handle);
NSetupConn(handle);
NSetupRow(handle);
TFScan(handle);
TFDone(handle);
NDoGroup(&(Tbase->connlist),NLinkConn);
/* put together the box/conn/net links */
return Tbase;
}
int /* 0 if error */
NRead(filename)
char *filename;
{
Nbase *newbase;
newbase = NReadNetwork(filename);
if (newbase) {
NFreeNetwork(NCurBase);
NCurBase = newbase;
/* Note that Tbase==NCurBase at this point, which is important! */
return 1; /* all OK */
}
return 0; /* no go */
}
int
NWrite(filename)
char *filename;
{
FILE *f;
int t;
if (!NCurBase) {
printf("no data to write");
return 0;
}
if (strcmp(filename,"stdout")==0) f=stdout;
else if (strcmp(filename,"stderr")==0) f=stderr;
else f=fopen(filename,"w");
if (!f) {
printf("can't open file %s for output\n",filename);
return 0;
}
fprintf(f,"/* TF netlist */\n");
/*** should add date, etc. */
NWriteGlobals(f,NCurBase);
NDumpGroup(f,&(NCurBase->boxlist),NWriteBox);
NDumpGroup(f,&(NCurBase->netlist),NWriteNet);
NDumpGroup(f,&(NCurBase->connlist),NWriteConn);
NDumpGroup(f,&(NCurBase->rowlist),NWriteRow);
fprintf(f,"/* end */\n");
if (f==stdout || f==stderr) fflush(f);
else {
t = ferror(f) || fclose(f);
if (t) {
printf("error closing file %s\n",filename);
return 0;
}
}
return 1;
}
static int
NDoPlot()
{
if (!(PInit(BBlow.X,BBlow.Y,BBhigh.X,BBhigh.Y))) {
printf("can't init plot\n");
return 0;
}
PTextSize(NCurBase->textsize.X,NCurBase->textsize.Y);
/* specify the size of text */
NDoGroup(&(NCurBase->boxlist),NPlotBox);
NDoGroup(&(NCurBase->netlist),NPlotNet);
NDoGroup(&(NCurBase->connlist),NPlotConn);
NDoGroup(&(NCurBase->rowlist),NPlotRow);
NPlotLabel(NCurBase);
PDone();
return 1;
}
static int
NBoundPlot()
{
if (!NCurBase) {
printf("no data to plot");
return 0;
}
NInitBB();
NDoGroup(&(NCurBase->boxlist),NBoundBox);
NDoGroup(&(NCurBase->netlist),NBoundNet);
NDoGroup(&(NCurBase->connlist),NBoundConn);
NDoGroup(&(NCurBase->rowlist),NBoundRow);
NSetLabel(NCurBase);
NBoundLabel(NCurBase);
return 1;
}
int
NPlot(ptype,filename)
char *ptype;
char *filename;
{
if (!NBoundPlot()) return 0;
if (!(PSetType(ptype,filename))) { return 0; }
return NDoPlot();
}
static int
NPartPlot(ptype,filename,xnum,ynum,lx,ly,hx,hy)
char *ptype;
char *filename;
int xnum,ynum; /* repetition numbers */
double lx,ly,hx,hy;
{
char nbuf[2000];
sprintf(nbuf,"%s_%d_%d",filename,xnum,ynum);
if (!(PSetType(ptype,nbuf))) { return 0; }
PSetWindow(lx,ly,hx,hy);
return NDoPlot();
}
int
NPlot4(ptype,filename)
char *ptype;
char *filename;
{
return NPlotXY(ptype,filename,2,2);
}
#define MAXPLOTREP 64
int
NPlotXY(ptype,filename,xnum,ynum)
char *ptype;
char *filename;
int xnum,ynum;
{
int x,y;
double xinc, yinc;
double xbase,ybase;
if (xnum<=0 || ynum<=0 || xnum>MAXPLOTREP || ynum>MAXPLOTREP) {
printf("Bad repeat number\n");
return 0;
}
if (!NBoundPlot()) return 0;
xinc = 1.0/(double)xnum;
yinc = 1.0/(double)ynum;
xbase = 0.;
for (x=0; x<xnum; x++) {
ybase = 0.;
for (y=0; y<ynum; y++) {
if (!NPartPlot(ptype,filename,x,y,
xbase,ybase,xbase+xinc,ybase+yinc)) return 0;
ybase += yinc;
}
xbase += xinc;
}
return 1;
}
char *
TFlags(flags)
char *flags;
{
int i;
char *cp, *np;
if (!flags) flags="";
switch (flags[0]) {
case '=':
for (i=0; i<Tflagcount; i++) Tflag[i]=0;
/* FALL THROUGH */
case '+':
for (cp=flags+1; *cp; cp++)
Tflag[*cp] = 1;
break;
case '-':
for (cp=flags+1; *cp; cp++)
Tflag[*cp] = 0;
break;
case '?':
case '\0':
break; /* just return the value */
case 'h':
TFlagsHelp();
break;
default:
break; /*** should output error message */
}
for (np=Tflagr, i=0; i<Tflagcount; i++)
if (Tflag[i]) *np++ = i;
*np = '\0';
return Tflagr;
}
TFlagsHelp()
{
printf("TFlags [+-=?][flagchars]\n");
printf("c enables plotting of connectors\n");
printf("f enables plotting of feedthough boxes\n");
printf("l enables label where text normally goes in boxes\n");
printf("m memory debugging - makes free not do anything\n");
printf("T disables normal text in boxes\n");
}
/* end */